package com.boarsoft.boar.deploy.plan.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.common.Constants;
import com.boarsoft.boar.deploy.common.BuildContext;
import com.boarsoft.boar.deploy.entity.BuildPlan;
import com.boarsoft.boar.deploy.entity.BuildPlanItem;
import com.boarsoft.boar.deploy.plan.PlanBiz;
import com.boarsoft.boar.deploy.plan.PlanItemBiz;
import com.boarsoft.boar.deploy.service.DeployService;
import com.boarsoft.common.Authorized;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.flow.core.SimpleFlow;
import com.boarsoft.flow.core.SimpleFlowEngine;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@RestController
@RequestMapping("/plan")
public class PlanAction {
	private static final Logger log = LoggerFactory.getLogger(PlanAction.class);

	@Autowired
	private PlanBiz planBiz;
	@Autowired
	private SimpleFlowEngine flowEngine;
	@Autowired
	private PlanItemBiz planItemBiz;
	@Autowired
	private DeployService deploySvc;

	@RequestMapping("/pack.do")
	@Authorized(code = "deploy.plan.pack")
	public ReplyInfo<Object> pack(String planId, String targetIds, short policy, String sessionId, String env) {
		BuildPlan plan = planBiz.get(planId);
		String dc = plan.getPackCode();
		if (flowEngine.exists(dc)) {
			// 构造数据
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("planId", planId);
			// 查询用户指定的要打包的项（应用）
			List<BuildPlanItem> items = new ArrayList<BuildPlanItem>();
			for (String targetId : targetIds.split(",")) {
				BuildPlanItem a = planItemBiz.get(targetId);
				items.add(a);
			}
			data.put("items", items);
			//
			String flowId = dc;
			SimpleFlow flow = flowEngine.create(flowId);
			flow.setData(data);
			if (BuildContext.putBuild(flowId, flow)) {
				try {
					flowEngine.start(flow);
					return ReplyInfo.SUCCESS;
				} catch (Throwable throwable) {
					log.error("Error on start flow {}", flow);
					return new ReplyInfo<Object>(Constants.ERROR_INTERNAL);
				}
			}
			return new ReplyInfo<Object>(String.format(//
					"Last build of plan %s is still running", flowId));
		}
		// TODO 调用JENKINS
		return ReplyInfo.SUCCESS;
	}

	/**
	 * 基于部署策略执行整个部署计划
	 * 
	 * @param planId
	 * @param policy
	 * @param sessionId
	 * @param env
	 * @return
	 */
	@RequestMapping("/deploy.do")
	@Authorized(code = "deploy.plan.deploy")
	public ReplyInfo<Object> deploy(String planId, String targetIds, short policy, String sessionId, String env) {
		BuildPlan plan = planBiz.get(planId);
		String dc = plan.getDeployCode();
		if (flowEngine.exists(dc)) {
			// 构造数据
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("planId", planId);
			// 查询用户指定的要打包的项（应用）
			List<BuildPlanItem> items = new ArrayList<BuildPlanItem>();
			for (String targetId : targetIds.split(",")) {
				BuildPlanItem a = planItemBiz.get(targetId);
				items.add(a);
			}
			data.put("items", items);
			//
			String flowId = dc;
			SimpleFlow flow = flowEngine.create(flowId);
			flow.setData(data);
			if (BuildContext.putBuild(flowId, flow)) {
				try {
					flowEngine.start(flow);
					return ReplyInfo.SUCCESS;
				} catch (Throwable throwable) {
					log.error("Error on start flow {}", flow);
					return new ReplyInfo<Object>(Constants.ERROR_INTERNAL);
				}
			}
			return new ReplyInfo<Object>(String.format(//
					"Last build of plan %s is still running", flowId));

		}
		// TODO 调用JENKINS
		return ReplyInfo.SUCCESS;
	}

	/**
	 * 导出部署计划
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping("/export.do")
	@Authorized(code = "deploy.plan.export")
	public ReplyInfo<Object> export_(String id) {
		return ReplyInfo.SUCCESS;
	}

	/**
	 * 导入部署计划
	 * 
	 * @param path
	 *            服务器上的绝对地址
	 * @return
	 */
	@RequestMapping("/import.do")
	@Authorized(code = "deploy.plan.import")
	public ReplyInfo<Object> import_(String path) {
		return ReplyInfo.SUCCESS;
	}

	@JsonIgnoreProperties({ "details", "servers", "packRecord", "deployRecord" })
	@RequestMapping("/list.do")
	@Authorized(code = "deploy.plan.list")
	public ReplyInfo<Object> list(String projId, String key, String orderBy, int pageNo, int pageSize) {
		PagedResult<BuildPlan> pr = planBiz.list(projId, key, orderBy, pageNo, pageSize);
		return new ReplyInfo<Object>(true, pr);
	}

	@RequestMapping("/delete.do")
	@Authorized(code = "deploy.plan.delete")
	public ReplyInfo<Object> delete(String id) {
		planBiz.delete(id);// 级联删除
		return ReplyInfo.SUCCESS;
	}

	@JsonIgnoreProperties({ "details", "servers", "deployRecord", "packRecord" })
	@RequestMapping("/save.do")
	@Authorized(code = "deploy.plan.save")
	public ReplyInfo<Object> save(BuildPlan a) {
		planBiz.save(a);
		return new ReplyInfo<Object>(true, a);
	}

	@JsonIgnoreProperties({ "details", "servers", "deployRecord", "packRecord" })
	@RequestMapping("/get.do")
	@Authorized(code = "deploy.plan.get")
	public ReplyInfo<Object> get(String id) {
		BuildPlan o = planBiz.get(id);
		return new ReplyInfo<Object>(true, o);
	}

	@RequestMapping("/execute.do")
	@Authorized(code = "deploy.plan.deploy.execute")
	public ReplyInfo<Object> execute(String id, String env) {
		return deploySvc.execute(id, env);
	}

	@RequestMapping("/refresh.do")
	// @Authorized(code = "deploy.plan.refresh")
	public ReplyInfo<Object> refresh(String id, String env) {
		return deploySvc.refresh(id, env);
	}
}